//============================================================================================
/**
 * @file	trainer_card.c
 * @brief	トレーナーカード
 * @author	Nozomu Saito
 * @date	05.11.15
 */
//============================================================================================
#include "trcard_sys.h"
#include "gflib/touchpanel.h"
#include "system/arc_tool.h"
#include "system/arc_util.h"
#include "system/clact_tool.h"
#include "system/wipe.h"
#include "system/fontproc.h"
#include "system/pmfprint.h"

#include "system/snd_tool.h"
#include "trcard_snd_def.h"
#include "trcard_bmp.h"
#include "trcard_obj.h"
#include "trcard_cgx_def.h"
#include "application/app_tool.h"
#include "trainer_case.naix"

#include "savedata/config.h"
#include "msgdata/msg_trainerscard.h"
#include "msgdata/msg.naix"
#include "communication/wm_icon.h"
#include "communication/comm_system.h"

#define MIN_SCRUCH	(3)
#define MAX_SCRUCH	(40)
#define REV_SPEED	(FX32_SHIFT - wk->RevSpeed)

#define CGX_WIDE		(32)
#define BUTTON_CGX_POS	(4*CGX_WIDE)
#define	MAIN_BUTTON_CGX_SIZE	(4)
#define MAIN_BUTTON_POS_Y	(19)
#define MAIN_BUTTON_POS_X	(14)

#define NOBODY_CGX_POS	(5*CGX_WIDE+26)
#define	GYM_READER_CGX_SIZE	(5)
#define COVER_CGX_WIDTH	(16)

#define BADGE_BAD_PLTT_NO	(3)
#define UNI_TRAINER_PLTT_NO	(4)

#define TRC_BG_TRAINER		(GF_BGL_FRAME3_S)
#define TRC_BG_FONT			(GF_BGL_FRAME3_S)
#define TRC_BG_SIGN			(GF_BGL_FRAME3_S)
#define TRC_BG_MSG			(GF_BGL_FRAME0_S)
#define TRC_BG_BACK			(GF_BGL_FRAME1_S)
#define TRC_BG_CARD			(GF_BGL_FRAME2_S)
#define TRC_BG_BADGE_CASE	(GF_BGL_FRAME2_M)
#define TRC_BG_BADGE_BACK	(GF_BGL_FRAME3_M)

#define CARD_SCALE_MIN	(0x24)

#define UNION_TR_MAX	(16)

#define CARD_RANK_MAX	(5)

//#define PALETTE_DEBUG		//有効でパレットデバッグ

enum {
	SEQ_IN,
	SEQ_MAIN,
	SEQ_OUT,
	SEQ_REV,
	SEQ_SIGN_CALL,
	SEQ_SIGN,
	SEQ_COVER,
};

typedef enum {
	TRC_KEY_REQ_NONE = 0,
	TRC_KEY_REQ_TP_BEAT,
	TRC_KEY_REQ_TP_BRUSH,
	TRC_KEY_REQ_REV_BUTTON,
	TRC_KEY_REQ_SIGN_CALL,
	TRC_KEY_REQ_END_BUTTON,
}TRC_KEY_REQ;

typedef enum {
	COVER_CLOSE = 0,
	COVER_OPEN = 1,
}COVER_STATE;

#if 0
enum {
	CASE_BUTTON,
	BADGE0,
	BADGE1,
	BADGE2,
	BADGE3,
	BADGE4,
	BADGE5,
	BADGE6,
	BADGE7,
};
#endif

enum {
	ANIME_NOTHING,
	ANIME_BUTTON_PUSH,
	ANIME_BUTTON_PULL
};

#define TP_BTN_PY	(21*8)
#define TP_BTN_SY	(3*8-1)
#define TP_BTN_SPX	(0*8)
#define TP_BTN_SSX	(14*8)
#define TP_BTN_BPX	(24*8-1)
#define TP_BTN_BSX	(8*8)
#define TP_CARD_PX	(0)
#define TP_CARD_PY	(0)
#define TP_CARD_SX	(255)
#define TP_CARD_SY	(21*8)

#if 0
typedef struct {
	const RECT_HIT_TBL *const CoverTpRect[2];	//0:カバー閉じてるとき 1:カバー開けてるとき
}RECT_HIT_TBL_LIST;
#endif

//ユニオンルームトレーナー表示テーブル
static const int UniTrTable[UNION_TR_MAX] =
{
	//男
	NARC_trainer_case_trdp_schoolb256_NCGR,
	NARC_trainer_case_trdp_mushi256_NCGR,
	NARC_trainer_case_trdp_elitem256_NCGR,
	NARC_trainer_case_trdp_heads256_NCGR,
	NARC_trainer_case_trdp_iseki256_NCGR,
	NARC_trainer_case_trdp_karate256_NCGR,
	NARC_trainer_case_trdp_prince256_NCGR,
	NARC_trainer_case_trdp_espm256_NCGR,
	//女
	NARC_trainer_case_trdp_mini256_NCGR,
	NARC_trainer_case_trdp_battleg256_NCGR,
	NARC_trainer_case_trdp_sister256_NCGR,
	NARC_trainer_case_trdp_elitew256_NCGR,
	NARC_trainer_case_trdp_idol256_NCGR,
	NARC_trainer_case_trdp_madam256_NCGR,
	NARC_trainer_case_trdp_cowgirl256_NCGR,
	NARC_trainer_case_trdp_princess256_NCGR,
};

#ifdef PALETTE_DEBUG
static int pal_test;
static void DBG_ChgPal(void);
#endif

//============================================================================================
//	プロトタイプ宣言
//============================================================================================
static void AllocStrBuf( TR_CARD_WORK * wk );
static void FreeStrBuf( TR_CARD_WORK * wk );

static void SetTrCardVramBank(void);
static void SetTrCardBg( GF_BGL_INI * ini );
static void SetTrCardBgGraphic( TR_CARD_WORK * wk );

static void TrCardBgExit( GF_BGL_INI * ini );

static void CardDesignDraw(TR_CARD_WORK* wk);
static void CardDataDraw(TR_CARD_WORK* wk);
static BOOL CardRev(TR_CARD_WORK * wk );
static void CardRevAffineSet(TR_CARD_WORK* wk);
static int CheckInput(TR_CARD_WORK *wk);
static void SetCardPalette(const u8 inCardRank, const u8 inPokeBookHold, const u8 inVer);
static void SetCasePalette(const u8 inVersion);
static void SetUniTrainerPalette(const u8 inTrainerNo);

static void VBlankFunc( void * work );
static void DispTrainer(TR_CARD_WORK *wk);
static void ClearTrainer(TR_CARD_WORK *wk);

static void ResetAffinePlane(void);
static const u8 GetBadgeLevel(const int inCount);

static void MakeSignData(const u8 *inRawData, u8 *outData);
static void TransSignData(GF_BGL_INI * bgl,const int inFrame, const u8 *inSignData);
static void UpdatePlayTime(TR_CARD_WORK *wk, const u8 inUpdateFlg);

static int SignCall( TR_CARD_WORK *wk );

static void ButtonVanish( TR_CARD_WORK * wk, BOOL flg );


//============================================================================================
//	グローバル変数
//============================================================================================


//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：初期化
 *
 * @param	proc	プロセスデータ
 * @param	seq		シーケンス
 *
 * @return	処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT TrCardProc_Init( PROC * proc, int * seq )
{
	TR_CARD_WORK * wk;
	CONFIG*	configSave;	///<コンフィグセーブデータ

	sys_VBlankFuncChange( NULL, NULL );	// VBlankセット
	sys_HBlankIntrSet( NULL,NULL );		// HBlankセット

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane( 0 );
	GXS_SetVisiblePlane( 0 );
	WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
	WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
	WIPE_ResetWndMask(WIPE_DISP_MAIN);
	WIPE_ResetWndMask(WIPE_DISP_SUB);

	sys_KeyRepeatSpeedSet( 4, 8 );
	sys_CreateHeap( HEAPID_BASE_APP, HEAPID_TR_CARD, 0x50000 );

	wk = PROC_AllocWork( proc, sizeof(TR_CARD_WORK), HEAPID_TR_CARD );
	memset( wk, 0, sizeof(TR_CARD_WORK) );

///	APP_WipeStart( APP_WIPE_IN, HEAPID_TR_CARD );	// 輝度変更セット

	//引継ぎパラメータ取得
	wk->tcp = PROC_GetParentWork( proc );
	wk->TrCardData = &wk->tcp->TrCardData;
	wk->key_mode = KeyTouchStatus_CheckTouchOrKey((KEYTOUCH_STATUS*)wk->tcp->pKTStatus);

	configSave = SaveData_GetConfig((SAVEDATA*)wk->tcp->savedata);
	wk->msg_spd = CONFIG_GetMsgPrintSpeed(configSave);
	wk->win_type = CONFIG_GetWindowType(configSave);

	//通信中かどうか？
//	if( CommIsConnect(u16 netID) ){
    //BTS4909 通信チェックを接続人数から通信を初期化したかに変更
    //        ユニオンルーム内でトレーナーカードのサインが書けた為
	if(CommIsInitialize() == TRUE ){
		wk->isComm = TRUE;
	}

	if(wk->TrCardData->Clear_m != 0){	//月が0月でなければ、クリアしたとみなす
		wk->isClear = TRUE;
	}else{
		wk->isClear = FALSE;
	}
	//090622通信時、自分がクリアしていなかったらバッヂは8個まで対応 Ariizumi
	if( wk->isComm == TRUE )
	{
  	if( wk->tcp->isClearSelf == FALSE )
  	{
      wk->isClear = FALSE;
    }
  }

  //BTS4910 DPPtを見たときバッジを消す処理でアイコンまで消してしまっていたのでフラグを消す処理に修正
	if ((wk->TrCardData->Version == VERSION_GOLD)||
			(wk->TrCardData->Version == VERSION_SILVER) )
	{
		int i;
		u16 flag  = 1;
		for(i=0;i<TR_BADGE_NUM_MAX;i++){
			if(wk->TrCardData->gs_badge & flag){
				wk->badge[i] = 1;
			}else{
				wk->badge[i] = 0;
			}
			flag <<= 1;
		}
	}
	else
	{
		int i;
		for(i=0;i<TR_BADGE_NUM_MAX;i++)
		{
				wk->badge[i] = 0;
		}
  }


	wk->bgl = GF_BGL_BglIniAlloc( HEAPID_TR_CARD );

	AllocStrBuf(wk);

	SetTrCardVramBank();
	SetTrCardBg( wk->bgl );
	SetTrCardBgGraphic( wk );

	InitTPSystem();						// タッチパネルシステム初期化
	InitTPNoBuff(4);

	// タッチメッセージ送り有効
	MsgPrintTouchPanelFlagSet( 1 );

	//音関連初期化
	Snd_DataSetByScene( SND_SCENE_SUB_TRCARD, 0, 0 ); //サウンドデータロード(BGM引継ぎ)
	Snd_BadgeWorkInit( &wk->SndBadgeWork );
	Snd_SePlay( SND_TRCARD_CALL );		//呼び出し音

	InitTRCardCellActor( &wk->ObjWork );

	SetTrCardActor( &wk->ObjWork, wk->badge ,wk->isClear);
	SetTrCardActorSub( &wk->ObjWork);

	//Bmpウィンドウ初期化
	TRCBmp_AddTrCardBmp( wk );

	//コロン描く
	TRCBmp_WriteSec(&(wk->win[TRC_BMPWIN_PLAY_TIME]), TRUE, wk->SecBuf);

	if(wk->tcp->value){
		wk->is_back = TRUE;
	}else{
		wk->is_back = FALSE;		//表面からスタート
	}
	wk->tcp->value = FALSE;
	wk->IsOpen = COVER_CLOSE;			//ケースは閉じた状態からスタート

	wk->touch = RECT_HIT_NONE;			//タッチパネルは押されていない

	wk->ButtonPushFlg = FALSE;			//ボタン押されてない
	wk->AnimeType = ANIME_NOTHING;		//ボタンアニメ無し

	//拡縮面をリセット
	ResetAffinePlane();

	//カードの初期状態表示
	CardDataDraw(wk);

	//戻るボタン描画
	TRCBmp_WriteBackButton(wk,FALSE);

	sys_VBlankFuncChange(VBlankFunc, wk );	// VBlankセット

	//通信アイコンセット
	// 受信強度アイコンを通信接続中なら表示するし、
	// ユニオンのように通信回路は動作しているが接続はしていない状態なら出さない
	// Change by Mori 2006/07/19
	WirelessIconEasyUnion();

	//BGMをしぼる
	//Snd_BgmFadeOut( BGM_VOL_TR_CASE, BGM_FADE_TR_CASE_TIME );
	Snd_PlayerSetPlayerVolume( PLAYER_FIELD, SND_PLAYER_VOL_TR_CASE );

	WIPE_SYS_Start(	WIPE_PATTERN_FSAM, WIPE_TYPE_SHUTTERIN_DOWN,
					WIPE_TYPE_SHUTTERIN_DOWN, WIPE_FADE_BLACK,
					WIPE_DEF_DIV, WIPE_DEF_SYNC, HEAPID_TR_CARD );

	//BTS1131↓
  //090622 DPPtのカードを見たときバッジを消す処理 Ariizumi
  //BTS4896 090624位置が悪かったので下に移動した
  //BTS4910 通信アイコンまで消えてしまったのでOBJを消すのは取り消し。Badgeフラグで対処
	if ((wk->TrCardData->Version != VERSION_GOLD)&&
			(wk->TrCardData->Version != VERSION_SILVER) )
	{
		GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG2 , VISIBLE_OFF );
		//GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_OFF );
	}



	return PROC_RES_FINISH;
}

//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：メイン
 *
 * @param	proc	プロセスデータ
 * @param	seq		シーケンス
 *
 * @return	処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT TrCardProc_Main( PROC * proc, int * seq )
{
	TR_CARD_WORK * wk  = PROC_GetWork( proc );

	switch( *seq ){
	case SEQ_IN:
		if( WIPE_SYS_EndCheck() ){
			*seq = SEQ_MAIN;
		}
		break;

	case SEQ_MAIN:
		{
			int req;
			req = CheckInput(wk);
#ifdef PALETTE_DEBUG
			 DBG_ChgPal();
#endif
#if 0
			if (wk->TrCardData->BrushValid){
				ClearScruchSnd(&wk->ScruchSnd);
			}
#endif
			if (req == TRC_KEY_REQ_REV_BUTTON){
				//カードひっくり返す
				wk->sub_seq = 0;	//サブシーケンス初期化
				*seq = SEQ_REV;	//カード回転
			}else if(req == TRC_KEY_REQ_SIGN_CALL){
				SetSActDrawSt(&wk->ObjWork,ACTS_BTN_SIGN,ANMS_SIGN_ON,TRUE);
//				SetEffActDrawSt(&wk->ObjWork, ACTS_BTN_SIGN ,TRUE);
				wk->sub_seq = 0;
				*seq = SEQ_SIGN_CALL;
			}else if (req == TRC_KEY_REQ_END_BUTTON){
				//終了
				SetSActDrawSt(&wk->ObjWork,ACTS_BTN_BACK,ANMS_BACK_ON,TRUE);
//				SetEffActDrawSt(&wk->ObjWork, ACTS_BTN_BACK ,TRUE);
				WIPE_SYS_Start(	WIPE_PATTERN_FMAS, WIPE_TYPE_SHUTTEROUT_UP,
								WIPE_TYPE_SHUTTEROUT_UP, WIPE_FADE_BLACK,
								WIPE_DEF_DIV, WIPE_DEF_SYNC, HEAPID_TR_CARD );
				*seq = SEQ_OUT;
			}
			UpdatePlayTime(wk, wk->TrCardData->TimeUpdate);
		}
		break;

	case SEQ_OUT:
		if( WIPE_SYS_EndCheck() ){
			return PROC_RES_FINISH;
		}
		break;

	case SEQ_REV:	//リバース処理
		if ( CardRev(wk) ){
			*seq = SEQ_MAIN;
		}
		break;
	case SEQ_SIGN_CALL:	//サイン処理を呼び出すか？
		{
			int ret;
			ret = SignCall(wk);
			switch(ret){
			case 1:
				*seq = SEQ_MAIN;
				break;
			case 2:
				*seq = SEQ_SIGN;
				break;
			}
		}
		break;
	case SEQ_SIGN:	//サイン処理を呼ぶ
		WIPE_SYS_Start(	WIPE_PATTERN_FMAS, WIPE_TYPE_SHUTTEROUT_UP,
						WIPE_TYPE_SHUTTEROUT_UP, WIPE_FADE_BLACK,
						WIPE_DEF_DIV, WIPE_DEF_SYNC, HEAPID_TR_CARD );
		wk->tcp->value = TRUE;
		*seq = SEQ_OUT;
		break;
	}
	if(++wk->scrl_ct >= 128){
		wk->scrl_ct = 0;
	}
	CLACT_Draw( wk->ObjWork.ClactSet );									// セルアクター常駐関数

	return PROC_RES_CONTINUE;
}

//--------------------------------------------------------------------------------------------
/**
 * プロセス関数：終了
 *
 * @param	proc	プロセスデータ
 * @param	seq		シーケンス
 *
 * @return	処理状況
 */
//--------------------------------------------------------------------------------------------
PROC_RESULT TrCardProc_End( PROC * proc, int * seq )
{
	TR_CARD_WORK * wk  = PROC_GetWork( proc );

	//使用した拡縮面を元に戻す
	ResetAffinePlane();

	FreeStrBuf( wk );					//文字列解放

	RereaseCellObject(&wk->ObjWork);		//2Dオブジェクト関連領域解放

	sys_FreeMemoryEz( wk->TrArcData );	//トレーナーキャラアーカイブデータ解放

	sys_FreeMemoryEz( wk->pScrnBCase );	//バッジケースクリーン解放
	sys_FreeMemoryEz( wk->TrScrnArcData );//トレーナースクリーン解放

	TRCBmp_ExitTrCardBmpWin( wk );			// BMPウィンドウ開放
	TrCardBgExit( wk->bgl );			// BGL削除
	StopTP();							// タッチパネル終了

	// タッチメッセージ送り無効
	MsgPrintTouchPanelFlagSet( 0 );

	//動作モード書き戻し
	KeyTouchStatus_SetTouchOrKey((KEYTOUCH_STATUS*)wk->tcp->pKTStatus,wk->key_mode);

	PROC_FreeWork( proc );				// ワーク開放

	sys_VBlankFuncChange( NULL, NULL );		// VBlankセット
	sys_DeleteHeap( HEAPID_TR_CARD );

	//BGMを元の音量に戻す
	//Snd_BgmFadeIn( BGM_VOL_MAX, BGM_FADE_TR_CASE_TIME, BGM_FADEIN_START_VOL_NOW );
	Snd_PlayerSetPlayerVolume( PLAYER_FIELD, SND_PLAYER_DEFAULT_VOL );

	return PROC_RES_FINISH;
}

//--------------------------------------------------------------------------------------------
/**
 * 文字列バッファの確保
 *
 * @param	wk		画面のワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void AllocStrBuf( TR_CARD_WORK * wk )
{
	int i;

	//フォント読み込み
	FontProc_LoadFont(FONT_TOUCH,HEAPID_TR_CARD);

	wk->msgMan = MSGMAN_Create(MSGMAN_TYPE_NORMAL, ARC_MSG, NARC_msg_trainerscard_dat, HEAPID_TR_CARD);

	//固定のバッファ作成
	wk->PlayTimeBuf = STRBUF_Create(TIME_H_DIGIT+1, HEAPID_TR_CARD);
	wk->TmpBuf = STRBUF_Create(TR_STRING_LEN, HEAPID_TR_CARD);
	wk->DigitBuf = STRBUF_Create(TR_DIGIT_LEN, HEAPID_TR_CARD);
	wk->SecBuf =	STRBUF_Create(5, HEAPID_TR_CARD);

	//固定文字列取得
	MSGMAN_GetString(wk->msgMan, MSG_TCARD_12, wk->SecBuf);

	for(i = 0;i < 3;i++){
		wk->ExpBuf[i] = MSGMAN_AllocString(wk->msgMan, MSG_TCARD_BACK+i);
	}
	for(i = 0;i < 2;i++){
		wk->SignBuf[i] = MSGMAN_AllocString(wk->msgMan, MSG_TCARD_SIGN01+i);
	}
	for(i = 0;i < TR_CPRM_STR_MAX;i++){
		wk->CPrmBuf[i] = MSGMAN_AllocString(wk->msgMan, MSG_TCARD_01+i);
	}
}

//--------------------------------------------------------------------------------------------
/**
 * 文字列バッファの解放
 *
 * @param	wk		画面のワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void FreeStrBuf( TR_CARD_WORK * wk )
{
	int i;

	for(i = 0;i < TR_CPRM_STR_MAX;i++){
		STRBUF_Delete( wk->CPrmBuf[i] );
	}
	STRBUF_Delete( wk->SignBuf[1] );
	STRBUF_Delete( wk->SignBuf[0] );

	STRBUF_Delete( wk->ExpBuf[2] );
	STRBUF_Delete( wk->ExpBuf[1] );
	STRBUF_Delete( wk->ExpBuf[0] );

	STRBUF_Delete( wk->SecBuf );
	STRBUF_Delete( wk->DigitBuf );
	STRBUF_Delete( wk->TmpBuf );
	STRBUF_Delete( wk->PlayTimeBuf );

	MSGMAN_Delete( wk->msgMan );

	FontProc_UnloadFont(FONT_TOUCH);
}

//--------------------------------------------------------------------------------------------
/**
 * VRAM設定
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetTrCardVramBank(void)
{
	GF_BGL_DISPVRAM tbl = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット

		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット

		GX_VRAM_OBJ_128_B,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット

		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット

		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &tbl );
}

//--------------------------------------------------------------------------------------------
/**
 * カードパレット設定
 *
 * @param	inCardRank		カードランク
 * @param	inPokeBookHold	図鑑所持フラグ
 * @param	inVer			カセットバージョン
 *
 * @return	なし
 */
//--------------------------------------------------------------------------------------------
static void SetCardPalette(const u8 inCardRank, const u8 inPokeBookHold, const u8 inVer)
{
	{
		int pal;
		void *buf;
		NNSG2dPaletteData *dat;

		if ( (inVer == VERSION_GOLD)||(inVer == VERSION_SILVER) ){
			if (inPokeBookHold){
				const int pal_gs[] = {
					NARC_trainer_case_card_0_NCLR,
					NARC_trainer_case_card_1_NCLR,
					NARC_trainer_case_card_2_NCLR,
					NARC_trainer_case_card_3_NCLR,
					NARC_trainer_case_card_4_NCLR,
					NARC_trainer_case_card_5_NCLR,
				};
				if (inCardRank>CARD_RANK_MAX){
					GF_ASSERT(0);
					pal = pal_gs[0];
				}else{
					pal = pal_gs[inCardRank];
				}

			}else{
				pal = NARC_trainer_case_card_6_NCLR;
			}
		}else if(inVer == VERSION_DIAMOND){
			const int pal_dia[] = {
				NARC_trainer_case_card_7_NCLR,
				NARC_trainer_case_card_8_NCLR,
				NARC_trainer_case_card_9_NCLR,
				NARC_trainer_case_card_10_NCLR,
				NARC_trainer_case_card_11_NCLR,
				NARC_trainer_case_card_12_NCLR,
			};

			if (inCardRank>CARD_RANK_MAX){
				GF_ASSERT(0);
				pal = pal_dia[0];
			}else{
				pal = pal_dia[inCardRank];
			}
		}else if(inVer == VERSION_PEARL){
			const int pal_pal[] = {
				NARC_trainer_case_card_13_NCLR,
				NARC_trainer_case_card_14_NCLR,
				NARC_trainer_case_card_15_NCLR,
				NARC_trainer_case_card_16_NCLR,
				NARC_trainer_case_card_17_NCLR,
				NARC_trainer_case_card_18_NCLR,
			};

			if (inCardRank>CARD_RANK_MAX){
				GF_ASSERT(0);
				pal = pal_pal[0];
			}else{
				pal = pal_pal[inCardRank];
			}
		}else if(inVer == VERSION_PLATINUM){
			const int pal_pl[] = {
				NARC_trainer_case_card_19_NCLR,
				NARC_trainer_case_card_20_NCLR,
				NARC_trainer_case_card_21_NCLR,
				NARC_trainer_case_card_22_NCLR,
				NARC_trainer_case_card_23_NCLR,
				NARC_trainer_case_card_24_NCLR,
			};
			if (inCardRank>CARD_RANK_MAX){
				GF_ASSERT(0);
				pal = pal_pl[0];
			}else{
				pal = pal_pl[inCardRank];
			}
		}else{
			GF_ASSERT(0);
			pal = NARC_trainer_case_card_0_NCLR;
		}

		buf = ArcUtil_PalDataGet(
					ARC_TR_CASE_GRA, pal, &dat, HEAPID_TR_CARD );

		{
			u16 * adr;
			DC_FlushRange( dat->pRawData, 2*16*16 );	//16本分をフラッシュ
			adr = dat->pRawData;
			//16パレット１番目から8本分ロード
			GXS_LoadBGPltt( &adr[16], 2*16, 2*16*8 );
			//f番目のパレット１本をロード
			GXS_LoadBGPltt( &adr[16*15], 2*16*15, 2*16 );
			sys_FreeMemoryEz(buf);
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 * ケースパレットセット
 *
 * @param	inVersion	バージョン
 *
 * @return	なし
 */
//--------------------------------------------------------------------------------------------
static void SetCasePalette(const u8 inVersion)
{
	void *buf;
	NNSG2dPaletteData *dat;
	switch(inVersion){
	case VERSION_DIAMOND:		//ダイヤ
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_case_d_NCLR, &dat, HEAPID_TR_CARD );
		break;
	case VERSION_PEARL:		//パール
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_case_p_NCLR, &dat, HEAPID_TR_CARD );
		break;
	case VERSION_GOLD:
	case VERSION_SILVER:
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_case_g_NCLR, &dat, HEAPID_TR_CARD );
		break;
	case VERSION_PLATINUM:
	default:	//別バージョン
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_case_x_NCLR, &dat, HEAPID_TR_CARD );
		break;
	}

	DC_FlushRange( dat->pRawData, 2*16 );
	GX_LoadBGPltt( dat->pRawData, CASE_BD_PAL*32, 2*16 );
	GXS_LoadBGPltt( dat->pRawData, CASE_BD_PAL*32, 2*16 );
	sys_FreeMemoryEz(buf);
}

//--------------------------------------------------------------------------------------------
/**
 * ユニオントレーナーパレットセット
 *
 * @param	inTrainerNo
 *
 * @return	なし
 */
//--------------------------------------------------------------------------------------------
static void SetUniTrainerPalette(const u8 inTrainerNo)
{
	void *buf;
	u8 *addr;
	NNSG2dPaletteData *dat;
	buf = ArcUtil_PalDataGet(
			ARC_TR_CASE_GRA, NARC_trainer_case_trdp_union_card_NCLR, &dat, HEAPID_TR_CARD );

	addr = (u8*)(dat->pRawData);

	DC_FlushRange(&addr[2*16*inTrainerNo] , 2*16 );
	GXS_LoadBGPltt( &addr[2*16*inTrainerNo], 2*16*UNI_TRAINER_PLTT_NO, 2*16 );
	sys_FreeMemoryEz(buf);
}

//--------------------------------------------------------------------------------------------
/**
 * BG設定
 *
 * @param	ini		BGLデータ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetTrCardBg( GF_BGL_INI * ini )
{

	GX_SetDispSelect(GX_DISP_SELECT_MAIN_SUB);

	{	// BG SYSTEM
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BGMODE_5, GX_BG0_AS_2D,
		};
		GF_BGL_InitBG( &BGsys_data );
	}

	{	// FONT (BMP)
		GF_BGL_BGCNT_HEADER ExAffineBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_256,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x18000, GX_BG_EXTPLTT_01,
			1, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( ini, TRC_BG_FONT, &ExAffineBgCntDat, GF_BGL_MODE_256X16 );
		GF_BGL_ScrClear( ini, TRC_BG_FONT );
	}

	{	// BG (CASE CHAR,MSG_CHAR)
		GF_BGL_BGCNT_HEADER TextBgCntDat[] = {
		 {	0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xd800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			0, 0, 0, FALSE},
		 {	0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			3, 0, 0, FALSE},
		};
		GF_BGL_BGControlSet( ini, TRC_BG_MSG,  &TextBgCntDat[0], GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( ini, TRC_BG_MSG );
		GF_BGL_BGControlSet( ini, TRC_BG_BACK, &TextBgCntDat[1], GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( ini, TRC_BG_BACK );
	}

	{	// BG (CARD CHAR)
		GF_BGL_BGCNT_HEADER AffineBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_256,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			2, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( ini, TRC_BG_CARD, &AffineBgCntDat, GF_BGL_MODE_256X16 );
		GF_BGL_ScrClear( ini, TRC_BG_CARD );
	}

	{	// BG (BADGE_CASE CHAR)
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			2, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( ini, TRC_BG_BADGE_CASE, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( ini, TRC_BG_BADGE_CASE );
	}

	{	// BG (BADGE_BACK CHAR)
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			3, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( ini, TRC_BG_BADGE_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( ini, TRC_BG_BADGE_BACK );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * グラフィックデータセット
 *
 * @param	wk		画面のワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void SetTrCardBgGraphic( TR_CARD_WORK * wk )
{
	// TRAINER_PALETTE(UP_DISPLAY)
	{
		void *buf;
		NNSG2dPaletteData *dat;
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_0_NCLR, &dat, HEAPID_TR_CARD );
		DC_FlushRange( dat->pRawData, 2*16*16 );
		GXS_LoadBGPltt( dat->pRawData, 0, 2*16*16 );
		sys_FreeMemoryEz(buf);
	}

	// CARD PALETTE
	SetCardPalette(wk->TrCardData->CardRank, wk->TrCardData->PokeBookFlg, wk->TrCardData->Version);

	// UNSER_CASE_COVER PALETTE(UNDER_DISPLAY)
	{
		void *buf;
		NNSG2dPaletteData *dat;
		buf = ArcUtil_PalDataGet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_case_g_NCLR, &dat, HEAPID_TR_CARD );
		DC_FlushRange( dat->pRawData, 16*2*16 );
		GX_LoadBGPltt( dat->pRawData, 0, 16*2*16 );
		sys_FreeMemoryEz(buf);
	}
	// CASE PALETTE
	//BTS3860対応 バージョンで背景の色が変わっていたのはカット
	//SetCasePalette(wk->TrCardData->Version);


	//TRAINER
	if (wk->TrCardData->UnionTrNo == UNION_TR_NONE){
		{
			BOOL rc;
			//アーカイブデータ取得
			wk->TrArcData = ArcUtil_Load(	ARC_TR_CASE_GRA, NARC_trainer_case_card_trainer_NCGR,
											FALSE, HEAPID_TR_CARD, ALLOC_TOP );
			GF_ASSERT(wk->TrArcData!=NULL);
			rc = NNS_G2dGetUnpackedBGCharacterData( wk->TrArcData, &wk->TrCharData);
			GF_ASSERT(rc);
		}

		if (wk->TrCardData->TrSex == PM_MALE){
			//男
			wk->TrScrnArcData = ArcUtil_ScrnDataGet(ARC_TR_CASE_GRA, NARC_trainer_case_card_trainer01_NSCR,
													0, &wk->ScrnData, HEAPID_TR_CARD);
		}else{
			//女
			wk->TrScrnArcData = ArcUtil_ScrnDataGet(ARC_TR_CASE_GRA, NARC_trainer_case_card_trainer02_NSCR,
													0, &wk->ScrnData, HEAPID_TR_CARD);
		}
	}else{
		//ユニオンルームで他の人のデータを見る時
		{
			BOOL rc;
			//アーカイブデータ取得
			wk->TrArcData = ArcUtil_Load(	ARC_TR_CASE_GRA, UniTrTable[wk->TrCardData->UnionTrNo],
											FALSE, HEAPID_TR_CARD, ALLOC_TOP );
			GF_ASSERT(wk->TrArcData!=NULL);
			rc = NNS_G2dGetUnpackedBGCharacterData( wk->TrArcData, &wk->TrCharData);
			GF_ASSERT(rc);

			wk->TrScrnArcData = ArcUtil_ScrnDataGet(ARC_TR_CASE_GRA, NARC_trainer_case_card_test256_NSCR,
													0, &wk->ScrnData, HEAPID_TR_CARD);
			//トレーナーパレット変更
			SetUniTrainerPalette(wk->TrCardData->UnionTrNo);
		}
	}
	DispTrainer(wk);

	//CARD
	ArcUtil_BgCharSet(
			ARC_TR_CASE_GRA, NARC_trainer_case_card_NCGR, wk->bgl, TRC_BG_CARD, 0, 0, 0, HEAPID_TR_CARD );
	ArcUtil_ScrnSet(
			ARC_TR_CASE_GRA, NARC_trainer_case_card_faca_NSCR, wk->bgl, TRC_BG_CARD, 0, 0, 0, HEAPID_TR_CARD );
	//CASE
	ArcUtil_BgCharSet(
			ARC_TR_CASE_GRA, NARC_trainer_case_card_case_NCGR, wk->bgl, TRC_BG_BACK, 0, 0, 0, HEAPID_TR_CARD );
	ArcUtil_ScrnSet(
			ARC_TR_CASE_GRA, NARC_trainer_case_card_case_NSCR, wk->bgl, TRC_BG_BACK, 0, 0, 0, HEAPID_TR_CARD );

	//BADGE_CASE & BADGE_BACK
	ArcUtil_BgCharSet( ARC_TR_CASE_GRA, NARC_trainer_case_card_case2_NCGR,
		wk->bgl, TRC_BG_BADGE_CASE, 0, 0, 0, HEAPID_TR_CARD );

	//スクリーンデータ取得
	wk->pScrnBCase = ArcUtil_ScrnDataGet(ARC_TR_CASE_GRA, NARC_trainer_case_card_case4_NSCR,
							0, &wk->pSBCase, HEAPID_TR_CARD);

	if(wk->isClear){
		int i;
		ArcUtil_ScrnSet( ARC_TR_CASE_GRA, NARC_trainer_case_card_case3_NSCR,
			wk->bgl, TRC_BG_BADGE_CASE, 0, 0, 0, HEAPID_TR_CARD );
#if 0
		for(i = 0;i < 8;i++){
			if(wk->badge[i+8] == 0){
				GF_BGL_ScrWriteExpand(wk->bgl,TRC_BG_BADGE_CASE,
					LEADER_ICON_X+(LEADER_ICON_OX*(i%4)),LEADER_ICON_KY+(LEADER_ICON_OY*(i/4)),
					LEADER_ICON_SX,LEADER_ICON_SY,wk->pSBCase->rawData,0,LEADER_ICON_PY,
					wk->pSBCase->screenWidth/8,wk->pSBCase->screenHeight/8);
			}
		}
#endif
	}else{
		int i;
		ArcUtil_ScrnSet( ARC_TR_CASE_GRA, NARC_trainer_case_card_case2_NSCR,
			wk->bgl, TRC_BG_BADGE_CASE, 0, 0, 0, HEAPID_TR_CARD );
#if 0
		for(i = 0;i < 8;i++){
			if(wk->badge[i] == 0){
				GF_BGL_ScrWriteExpand(wk->bgl,TRC_BG_BADGE_CASE,
					LEADER_ICON_X+(LEADER_ICON_OX*(i%4)),LEADER_ICON_JY+(LEADER_ICON_OY*(i/4)),
					LEADER_ICON_SX,LEADER_ICON_SY,wk->pSBCase->rawData,0,LEADER_ICON_PY,
					wk->pSBCase->screenWidth/8,wk->pSBCase->screenHeight/8);
			}
		}
#endif
	}
	ArcUtil_ScrnSet( ARC_TR_CASE_GRA, NARC_trainer_case_card_case2bg_NSCR,
		wk->bgl, TRC_BG_BADGE_BACK, 0, 0, 0, HEAPID_TR_CARD );

	//殿堂入りマーク表示
	if(!wk->isClear && wk->TrCardData->gs_badge >= 0x00FF){
		GF_BGL_ScrWriteExpand(wk->bgl,TRC_BG_BADGE_CASE,
			0,7,7,9,wk->pSBCase->rawData,0,0,
			wk->pSBCase->screenWidth/8,wk->pSBCase->screenHeight/8);
	}else if(wk->TrCardData->gs_badge == 0xFFFF){
		GF_BGL_ScrWriteExpand(wk->bgl,TRC_BG_BADGE_CASE,
			0,14,7,9,wk->pSBCase->rawData,7,0,
			wk->pSBCase->screenWidth/8,wk->pSBCase->screenHeight/8);
	}
	GF_BGL_LoadScreenReq(wk->bgl,TRC_BG_BADGE_CASE);
	//サイン展開
	MakeSignData(wk->TrCardData->SignRawData, wk->TrSignData);

}

//--------------------------------------------------------------------------------------------
/**
 * BG解放
 *
 * @param	ini		BGLデータ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void TrCardBgExit( GF_BGL_INI * ini )
{
	GF_Disp_GX_VisibleControl(
		GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 |
		GX_PLANEMASK_BG3 | GX_PLANEMASK_OBJ, VISIBLE_OFF );
	GF_Disp_GXS_VisibleControl(
		GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 |
		GX_PLANEMASK_BG3 | GX_PLANEMASK_OBJ, VISIBLE_OFF );

	GF_BGL_ScrollSet( ini,TRC_BG_BACK, GF_BGL_SCROLL_X_SET, 0);
	GF_BGL_ScrollSet( ini,TRC_BG_BACK, GF_BGL_SCROLL_Y_SET, 0);
	GF_BGL_ScrollSet( ini,TRC_BG_BADGE_BACK, GF_BGL_SCROLL_X_SET, 0);
	GF_BGL_ScrollSet( ini,TRC_BG_BADGE_BACK, GF_BGL_SCROLL_Y_SET, 0);

	GF_BGL_BGControlExit( ini, TRC_BG_FONT );
	GF_BGL_BGControlExit( ini, TRC_BG_CARD );
	GF_BGL_BGControlExit( ini, TRC_BG_MSG );
	GF_BGL_BGControlExit( ini, TRC_BG_BACK );
	GF_BGL_BGControlExit( ini, TRC_BG_BADGE_CASE );
	GF_BGL_BGControlExit( ini, TRC_BG_BADGE_BACK );

	sys_FreeMemoryEz( ini );
}


//--------------------------------------------------------------------------------------------
/**
 *	@brief	wk->is_back変数の状態によって、カードの表or裏のViewをクリア＆書き込み
 */
//--------------------------------------------------------------------------------------------
static void CardDesignDraw(TR_CARD_WORK* wk)
{
	if (wk->is_back == FALSE){
		ArcUtil_ScrnSet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_faca_NSCR, wk->bgl, TRC_BG_CARD, 0, 0, 0, HEAPID_TR_CARD );
		//裏面を消す
		TRCBmp_NonDispWinInfo(wk->win, TRC_BMPWIN_CLEAR_TIME, TRC_BMPWIN_TRADE_INFO);
		//スクリーンクリア
		GF_BGL_ScrClear( wk->bgl, TRC_BG_TRAINER );
	}else{
		ArcUtil_ScrnSet(
				ARC_TR_CASE_GRA, NARC_trainer_case_card_back_NSCR, wk->bgl, TRC_BG_CARD, 0, 0, 0, HEAPID_TR_CARD );
		//表面を消す
		TRCBmp_NonDispWinInfo(wk->win, TRC_BMPWIN_TR_ID, TRC_BMPWIN_START_TIME);
		//トレーナー消す
		ClearTrainer(wk);
		//スクリーンクリア
		GF_BGL_ScrClear( wk->bgl, TRC_BG_SIGN );
	}
}

//--------------------------------------------------------------------------------------------
/**
 *	@brief	wk->is_back変数の状態によって、カードの表or裏のViewを作成
 */
//--------------------------------------------------------------------------------------------
static void CardDataDraw(TR_CARD_WORK* wk)
{
	//背景デザイン書き込み
	CardDesignDraw(wk);

	//戻るボタン表示
	SetSActDrawSt( &wk->ObjWork,ACTS_BTN_BACK,ANMS_BACK_OFF ,TRUE);

	if (wk->is_back == FALSE){	//表
		//トレーナー表示
		DispTrainer(wk);
		TRCBmp_WriteExpWin(wk,EXPWIN_PAT_TOUCH);
	}else{	//裏面表示
		TransSignData(wk->bgl,TRC_BG_SIGN, wk->TrSignData);
		TRCBmp_WriteExpWin(wk,EXPWIN_PAT_SIGN);
	}
	TRCBmp_WriteTrWinInfo(wk, wk->win, wk->TrCardData );
	TRCBmp_WriteTrWinInfoRev(wk, wk->win, wk->TrCardData );
	TRCBmp_TransTrWinInfo(wk,wk->win);
}

//--------------------------------------------------------------------------------------------
/**
 * サインアプリを呼ぶか確認
 *
 * @param	wk		画面のワーク
 *
 * @return	BOOL	TRUE:終了	FALSE：処理中
 */
//--------------------------------------------------------------------------------------------
static int SignCall( TR_CARD_WORK *wk )
{
	int ret = 0;

	switch(wk->sub_seq){
	case 0:	//サインを書きますか？
		TRCBmp_SignDrawMsgPut(wk,0);
		wk->sub_seq++;
		break;
	case 1:
		//描画終了待ち
		if( GF_MSG_PrintEndCheck( wk->msgIdx )){
			return 0;
		}
		TRCBmp_SignDrawYesNoCall(wk,0);
		ButtonVanish( wk, TRUE );
		wk->sub_seq++;
		break;
	case 2:	//選択待ち
		ret = TRCBmp_SignDrawYesNoWait(wk,0);
		if(ret < 0){
			break;
		}
		if(ret == 0){
			ButtonVanish( wk, FALSE );
			return 1;
		}
		if(wk->TrCardData->MySignValid){
			TRCBmp_SignDrawMsgPut(wk,1);
		}else{
			return 2;	//サインを書く
		}
		wk->sub_seq++;
		break;
	case 3:
		if( GF_MSG_PrintEndCheck( wk->msgIdx )){
			return 0;
		}
		TRCBmp_SignDrawYesNoCall(wk,1);
		wk->sub_seq++;
		break;
	case 4:	//元のデータが消えてもいいですか？
		ret = TRCBmp_SignDrawYesNoWait(wk,1);
		switch(ret){
		case 0:
			ButtonVanish( wk, FALSE );
			return 1;
		case 1:
			return 2;
		}
		break;
	}
	return 0;
}

#define FIRST_SPEED	(8)
//--------------------------------------------------------------------------------------------
/**
 * カードをひっくり返す
 *
 * @param	wk		画面のワーク
 *
 * @return	BOOL	TRUE:終了	FALSE：処理中
 */
//--------------------------------------------------------------------------------------------
static BOOL CardRev( TR_CARD_WORK *wk )
{
	BOOL rc;
	MtxFx22 mtx;
    fx32 rScale_x,rScale_y;
	rc = FALSE;
	switch(wk->sub_seq){
	case 0:
		wk->RevSpeed = FIRST_SPEED;
		//情報を消す
		//ちょっと拡大して
		wk->CardScaleX = 1 << FX32_SHIFT;
		wk->CardScaleY = 1 << FX32_SHIFT;
		wk->CardScaleX += 2 << (FX32_SHIFT - 6);
		wk->CardScaleY += 2 << (FX32_SHIFT - 6);

		Snd_SePlay( SND_TRCARD_REV );		//ひっくり返す音

		wk->sub_seq++;
		break;
	case 1:
		//幅を縮める
		wk->CardScaleX -= 2 << (REV_SPEED);
		if (wk->CardScaleX <= 0){//カードスクリーン変更
			wk->CardScaleX = CARD_SCALE_MIN;	//バグ表示防止(値はカードの厚みを維持できる位の目分量)
			wk->sub_seq++;
		}

		wk->RevSpeed--;
		if (wk->RevSpeed <=1 ){
			wk->RevSpeed = 1;
		}
		break;
	case 2:
		wk->is_back ^= 1;
		CardDesignDraw(wk);
		wk->sub_seq++;
		break;
	case 3:
		if (wk->is_back == FALSE){
			//トレーナー表示
			DispTrainer(wk);
			TRCBmp_WriteExpWin(wk,EXPWIN_PAT_TOUCH);
		}else{
			TransSignData(wk->bgl,TRC_BG_SIGN, wk->TrSignData);
			if(!wk->isComm){	//通信中は書換えなし
				TRCBmp_WriteExpWin(wk,EXPWIN_PAT_SIGN);
			}
		}
		wk->sub_seq++;
		break;
	case 4:
		TRCBmp_TransTrWinInfo(wk,wk->win);
		wk->sub_seq++;
		break;
	case 5:
		//幅を広げる
		wk->RevSpeed++;
		if(wk->RevSpeed > FIRST_SPEED){
			wk->RevSpeed = FIRST_SPEED;
		}

		wk->CardScaleX += 2 << (REV_SPEED);
		if (wk->CardScaleX >= (1 << FX32_SHIFT)){
			wk->CardScaleX = 1 << FX32_SHIFT;
			//元のサイズへ
			wk->CardScaleX = 1 << FX32_SHIFT;
			wk->CardScaleY = 1 << FX32_SHIFT;
			rc = TRUE;
		}
		break;
	}
	//アフィン変換実行リクエスト
	wk->aff_req = TRUE;
	return rc;
}

static void CardRevAffineSet(TR_CARD_WORK* wk)
{
	MtxFx22 mtx;

    mtx._00 = FX_Inv(wk->CardScaleX);
    mtx._01 = 0;
    mtx._10 = 0;
    mtx._11 = FX_Inv(wk->CardScaleY);
    SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup
	G2S_SetBG2Affine(&mtx,          // a matrix for rotation and scaling
                        128, 96,      // the center of rotation
                        0, 0           // the reference point before rotation and scaling applied
            );
	G2S_SetBG3Affine(&mtx,          // a matrix for rotation and scaling
                        128, 96,      // the center of rotation
                        0, 0           // the reference point before rotation and scaling applied
            );
	wk->aff_req = FALSE;
}

static int CheckKey(TR_CARD_WORK* wk)
{
	if ( sys.trg & PAD_BUTTON_DECIDE ){
		if(wk->is_back && (!wk->isComm)){
			//サインを書く
			Snd_SePlay( SND_TRCARD_SIGN );
			return TRC_KEY_REQ_SIGN_CALL;
		}
	}else if ( sys.trg & PAD_BUTTON_CANCEL ){
		Snd_SePlay( SND_TRCARD_END );		//終了音
		return TRC_KEY_REQ_END_BUTTON;
	}

	if(sys.trg & (PAD_KEY_LEFT|PAD_KEY_RIGHT)){
		return TRC_KEY_REQ_REV_BUTTON;
	}
	return TRC_KEY_REQ_NONE;
}
static int CheckTouch(TR_CARD_WORK* wk,BOOL* touch_f)
{
	int ret;
	u16	pat;
	static const RECT_HIT_TBL Btn_TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{TP_BTN_PY,TP_BTN_PY+TP_BTN_SY,TP_BTN_BPX,TP_BTN_BPX+TP_BTN_BSX},
		{TP_BTN_PY,TP_BTN_PY+TP_BTN_SY,TP_BTN_SPX,TP_BTN_SPX+TP_BTN_SSX},
		{TP_CARD_PY,TP_CARD_PY+TP_CARD_SY,TP_CARD_PX,TP_CARD_PX+TP_CARD_SX},
		{RECT_HIT_END,0,0,0}
	};

	if(GF_TP_GetTrg() == 0){
		return TRC_KEY_REQ_NONE;
	}

	//戻るボタン検出
	if(GF_TP_SingleHitTrg(&Btn_TpRect[0])){
		*touch_f = TRUE;
		Snd_SePlay( SND_TRCARD_END );		//終了音
		return TRC_KEY_REQ_END_BUTTON;
	}

	//サインを書くボタン検出
	if(wk->is_back && (!wk->isComm)){
		if(GF_TP_SingleHitTrg(&Btn_TpRect[1])){
			*touch_f = TRUE;
			Snd_SePlay( SND_TRCARD_SIGN );
			return TRC_KEY_REQ_SIGN_CALL;
		}
	}

	//現在の座標を取得
	if(GF_TP_SingleHitTrg(&Btn_TpRect[2])){
		wk->tp_x = sys.tp_x;
		wk->tp_y = sys.tp_y;
//		SetEffActDrawSt(&wk->ObjWork,ACTS_BTN_EFF,TRUE);
		*touch_f = TRUE;
		return TRC_KEY_REQ_REV_BUTTON;
	}
	return TRC_KEY_REQ_NONE;
}
static int CheckInput(TR_CARD_WORK *wk)
{
	int ret;
	int key_req = TRC_KEY_REQ_NONE;
	BOOL tp_key_flg = FALSE;
	BOOL touch_f = FALSE;

	wk->touch = RECT_HIT_NONE;

	ret = CheckTouch(wk,&touch_f);

	if(touch_f){
		wk->key_mode = APP_KTST_TOUCH;
		return ret;
	}
	ret = CheckKey(wk);
	if(ret != TRC_KEY_REQ_NONE){
		wk->key_mode = APP_KTST_KEY;
	}
	return ret;
}

//--------------------------------------------------------------------------------------------
/**
 * VBlank関数
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void VBlankFunc( void * work )
{
	TR_CARD_WORK* wk = (TR_CARD_WORK*)work;
	int scr;

	//背景スクロール
	scr = -(wk->scrl_ct);
	GF_BGL_ScrollSet( wk->bgl,TRC_BG_BACK, GF_BGL_SCROLL_X_SET,scr );
	GF_BGL_ScrollSet( wk->bgl,TRC_BG_BACK, GF_BGL_SCROLL_Y_SET,scr );
	GF_BGL_ScrollSet( wk->bgl,TRC_BG_BADGE_BACK, GF_BGL_SCROLL_X_SET, scr);
	GF_BGL_ScrollSet( wk->bgl,TRC_BG_BADGE_BACK, GF_BGL_SCROLL_Y_SET, scr);

	if(wk->aff_req){
		CardRevAffineSet(wk);
	}
	GF_BGL_VBlankFunc( wk->bgl );

	// セルアクター
	// Vram転送マネージャー実行
	DoVramTransferManager();

	// レンダラ共有OAMマネージャVram転送
	REND_OAMTrans();


	OS_SetIrqCheckFlag( OS_IE_V_BLANK );
}

//--------------------------------------------------------------------------------------------
/**
 * 拡縮面リセット
 *
 * @param	none
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void ResetAffinePlane(void)
{
	MtxFx22 mtx;
    fx32 rScale_x,rScale_y;

	rScale_x = FX_Inv((1 << FX32_SHIFT));
	rScale_y = FX_Inv((1 << FX32_SHIFT));
    mtx._00 = rScale_x;
    mtx._01 = 0;
    mtx._10 = 0;
    mtx._11 = rScale_y;
    SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup
	G2S_SetBG2Affine(&mtx,          // a matrix for rotation and scaling
                        128, 96,      // the center of rotation
                        0, 0           // the reference point before rotation and scaling applied
            );
	G2S_SetBG3Affine(&mtx,          // a matrix for rotation and scaling
                        128, 96,      // the center of rotation
                        0, 0           // the reference point before rotation and scaling applied
            );
	SVC_WaitVBlankIntr();          // Waiting the end of VBlank interrup
	G2_SetBG3Affine(&mtx,          // a matrix for rotation and scaling
                        128, 0,      // the center of rotation
                        0, 0           // the reference point before rotation and scaling applied
            );
}

//--------------------------------------------------------------------------------------------
/**
 * トレーナースクリーン転送
 *
 * @param	wk			画面のワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void DispTrainer(TR_CARD_WORK *wk)
{
	u32 transSize;

	transSize = wk->ScrnData->szByte;

	//TRAINER
	GF_BGL_LoadCharacter(wk->bgl, TRC_BG_TRAINER, wk->TrCharData->pRawData, wk->TrCharData->szByte, 0);

#if 0
	if( GF_BGL_ScreenAdrsGet( wk->bgl, TRC_BG_TRAINER ) != NULL ){
		GF_BGL_ScreenBufSet( wk->bgl, TRC_BG_TRAINER, wk->ScrnData->rawData, transSize );
	}

	GF_BGL_LoadScreen( wk->bgl, TRC_BG_TRAINER, wk->ScrnData->rawData, transSize, 0 );
#else
	GF_BGL_ScrWriteExpand(wk->bgl,TRC_BG_TRAINER,
		21,5,10,11,wk->ScrnData->rawData,21,5,
		wk->ScrnData->screenWidth/8,wk->ScrnData->screenHeight/8);
	GF_BGL_LoadScreenReq( wk->bgl, TRC_BG_TRAINER );
#endif
}

//--------------------------------------------------------------------------------------------
/**
 * トレーナースクリーンクリア
 *
 * @param	wk			画面のワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void ClearTrainer(TR_CARD_WORK *wk)
{
	GF_BGL_ScrFill(wk->bgl, TRC_BG_TRAINER, 0, 20, 6, 6, 9, GF_BGL_SCRWRT_PALNL);
}

//--------------------------------------------------------------------------------------------
/**
 * バッジレベル取得
 *
 * @param	inCount			磨き回数
 *
 * @return	u8				レベル
 */
//--------------------------------------------------------------------------------------------
static const u8 GetBadgeLevel(const int inCount)
{
	u8 lv;
	if ((0<=inCount)&&(inCount<COUNT_LV0)){
		lv = 0;
	}else if(inCount<COUNT_LV1){
		lv =1;
	}else if (inCount<COUNT_LV2){
		lv = 2;
	}else if (inCount<COUNT_LV3){
		lv = 3;
	}else if (inCount<COUNT_LV4){
		lv = 4;
	}else{
		GF_ASSERT(0&&"BadgeLevelOver");
		lv = 0;
	}
	return lv;
}

//--------------------------------------------------------------------------------------------
/**
 * サインデータ作成
 *
 * @param	*inRawData	ビット単位で持っているサインデータ
 * @param	*outData	サインデータ格納場所
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void MakeSignData(const u8 *inRawData, u8 *outData)
{

	int dot,raw_dot;
	u8 raw_line;	//0〜7
	u8 shift;		//0〜7
	for(dot=0;dot<SIGN_SIZE_X*SIGN_SIZE_Y*64;dot++){
		raw_dot = dot/64;
		raw_line = (dot/8)%8;
		shift = (dot%8);
		outData[dot] = ( 0x01 & (inRawData[(raw_dot*8)+raw_line]>>shift) );
	}
}

//--------------------------------------------------------------------------------------------
/**
 * サインデータ転送
 *
 * @param	bgl				bgl
 * @param	inFrame			対象フレーム
 * @param	inSignData		サインデータ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void TransSignData(GF_BGL_INI * bgl,const int inFrame, const u8 *inSignData)
{
	u16 *buf;
	u8 x,y;
	u16 count;

	GF_BGL_LoadCharacter( bgl, inFrame, inSignData, SIGN_BYTE_SIZE, SIGN_CGX );

	buf   = (u16 *)GF_BGL_ScreenAdrsGet( bgl, inFrame );

	count = 0;
	for( y=0; y<SIGN_SY; y++ ){
        for( x=0; x<SIGN_SX; x++ ){
            buf[ (SIGN_PY+y)*TRC_SCREEN_WIDTH + x+SIGN_PX ] = (SIGN_CGX+count);
			count++;
        }
    }
	GF_BGL_LoadScreenV_Req( bgl, inFrame );
}


//--------------------------------------------------------------------------------------------
/**
 * プレイ時間更新
 *
 * @param	wk				画面のワーク
 * @param	inUpdateFlg		時間更新フラグ
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
static void UpdatePlayTime(TR_CARD_WORK *wk, const u8 inUpdateFlg)
{
	//更新フラグがたっているかをチェック
	if (!inUpdateFlg){
		return;
	}

	if (!wk->is_back){	//表面の場合のみ描画
		if (wk->SecCount == 0){
			TRCBmp_WritePlayTime(wk->win, wk->TrCardData, wk->PlayTimeBuf);
			//コロン描く
			TRCBmp_WriteSec(&(wk->win[TRC_BMPWIN_PLAY_TIME]), TRUE, wk->SecBuf);
		}else if(wk->SecCount == 15){
			//コロン消す
			TRCBmp_WriteSec(&(wk->win[TRC_BMPWIN_PLAY_TIME]), FALSE, wk->SecBuf);
		}
	}
	//カウントアップ
	wk->SecCount = (wk->SecCount+1)%30;		//	1/30なので
}

// ボタン表示切替
static void ButtonVanish( TR_CARD_WORK * wk, BOOL flg )
{
	// 非表示
	if( flg == TRUE ){
		SetSActDrawSt( &wk->ObjWork, ACTS_BTN_SIGN, ANMS_SIGN_OFF, FALSE );
		SetSActDrawSt( &wk->ObjWork, ACTS_BTN_BACK, ANMS_BACK_OFF, FALSE );
	// 表示
	}else{
		SetSActDrawSt( &wk->ObjWork, ACTS_BTN_SIGN, ANMS_SIGN_OFF, TRUE );
		SetSActDrawSt( &wk->ObjWork, ACTS_BTN_BACK, ANMS_BACK_OFF, TRUE );
	}
	TRCBmp_ButtonVanish( wk, flg );
}




#ifdef PALETTE_DEBUG
static void DBG_ChgPal(void)
{
	void *buf;
	NNSG2dPaletteData *dat;
	const int test_pal[] = {
		NARC_trainer_case_card_0_NCLR,
		NARC_trainer_case_card_1_NCLR,
		NARC_trainer_case_card_2_NCLR,
		NARC_trainer_case_card_3_NCLR,
		NARC_trainer_case_card_4_NCLR,
		NARC_trainer_case_card_5_NCLR,
		NARC_trainer_case_card_6_NCLR,
		NARC_trainer_case_card_7_NCLR,
		NARC_trainer_case_card_8_NCLR,
		NARC_trainer_case_card_9_NCLR,
		NARC_trainer_case_card_10_NCLR,
		NARC_trainer_case_card_11_NCLR,
		NARC_trainer_case_card_12_NCLR,
		NARC_trainer_case_card_13_NCLR,
		NARC_trainer_case_card_14_NCLR,
		NARC_trainer_case_card_15_NCLR,
		NARC_trainer_case_card_16_NCLR,
		NARC_trainer_case_card_17_NCLR,
		NARC_trainer_case_card_18_NCLR,
		NARC_trainer_case_card_19_NCLR,
		NARC_trainer_case_card_20_NCLR,
		NARC_trainer_case_card_21_NCLR,
		NARC_trainer_case_card_22_NCLR,
		NARC_trainer_case_card_23_NCLR,
		NARC_trainer_case_card_24_NCLR
	};

	if (sys.trg & PAD_BUTTON_L){

		pal_test++;
		if (pal_test > 24){
			pal_test = 0;
		}
		//パレット変更
		buf = ArcUtil_PalDataGet(
					ARC_TR_CASE_GRA, pal_test, &dat, HEAPID_TR_CARD );

		{
			u16 * adr;
			DC_FlushRange( dat->pRawData, 2*16*16 );	//16本分をフラッシュ
			adr = dat->pRawData;
			//16パレット１番目から8本分ロード
			GXS_LoadBGPltt( &adr[16], 2*16, 2*16*8 );
			//f番目のパレット１本をロード
			GXS_LoadBGPltt( &adr[16*15], 2*16*15, 2*16 );
			sys_FreeMemoryEz(buf);
		}
	}else if (sys.trg & PAD_BUTTON_R){
		pal_test = 0;
		//パレット変更
		buf = ArcUtil_PalDataGet(
					ARC_TR_CASE_GRA, pal_test, &dat, HEAPID_TR_CARD );

		{
			u16 * adr;
			DC_FlushRange( dat->pRawData, 2*16*16 );	//16本分をフラッシュ
			adr = dat->pRawData;
			//16パレット１番目から8本分ロード
			GXS_LoadBGPltt( &adr[16], 2*16, 2*16*8 );
			//f番目のパレット１本をロード
			GXS_LoadBGPltt( &adr[16*15], 2*16*15, 2*16 );
			sys_FreeMemoryEz(buf);
		}
	}
}
#endif


